#include "FrameEleccionTabla.h"
#include "FrameDeEleccionDeFiltros.h"
#include "Columnas.h"

FrameEleccionTabla::FrameEleccionTabla(GestorArchivoConfiguracion& gestor):gestorConfigHechos(gestor) {
	inicializarVentanasDeslizables();

	tituloTabla.set_markup("<span><b>Selecciona una tabla</b></span>");
	cajaHTituloTabla.pack_start(tituloTabla, false, false, 25);	// **

	cajaHorizontal.pack_start(ventanaDeslizableArchivos, false, false, 25);
	cajaHorizontal.pack_start(ventanaDeslizableDimensiones, false, false, 15);
	cajaHorizontal.pack_start(ventanaDeslizableHechos, false, false, 15);	// **

	tituloGrafico.set_markup("<span><b>Seleccione un tipo de gráfico</b></span>");
	cajaHTituloGrafico.pack_start(tituloGrafico, false, false, 25);	// **

	cajaHGrafico.pack_start(ventanaDeslizableGraficos, false, false, 25);
	cajaHGrafico.pack_start(nota, false, false, 15);

	cajaVerticalGrafico.pack_start(cajaHTituloGrafico, false, false, 10);
	cajaVerticalGrafico.pack_start(cajaHGrafico, false, false, 5);

	cajaVertical.pack_start(cajaHTituloTabla, false, false, 18);
	cajaVertical.pack_start(cajaHorizontal, false, false, 0);
	cajaVertical.pack_start(cajaVerticalGrafico, false, false, 20);

	setDatosDeTablas();
	setNombresDatosGraficos();

	conectarManejadoresDeEvento();

	add(cajaVertical);
}


void FrameEleccionTabla::inicializarVentanasDeslizables() {
	ventanaDeslizableArchivos.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
	ventanaDeslizableArchivos.set_size_request(130, 150);
	referenciaModeloArchivos = Gtk::ListStore::create(columnasArchivos);
	visorModeloArbolArchivos.set_model(referenciaModeloArchivos);
	visorModeloArbolArchivos.append_column("             Tablas", columnasArchivos.idColumna);
	ventanaDeslizableArchivos.add(visorModeloArbolArchivos);

	ventanaDeslizableHechos.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
	ventanaDeslizableHechos.set_size_request(130, 150);
	referenciaModeloHechos = Gtk::ListStore::create(columnasHechos);
	visorModeloArbolHechos.set_model(referenciaModeloHechos);
	visorModeloArbolHechos.append_column("             Hechos", columnasHechos.idColumna);
	ventanaDeslizableHechos.add(visorModeloArbolHechos);

	ventanaDeslizableDimensiones.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
	ventanaDeslizableDimensiones.set_size_request(130, 150);
	referenciaModeloDimensiones = Gtk::ListStore::create(columnasDimensiones);
	visorModeloArbolDimensiones.set_model(referenciaModeloDimensiones);
	visorModeloArbolDimensiones.append_column("     Dimensiones", columnasDimensiones.idColumna);
	ventanaDeslizableDimensiones.add(visorModeloArbolDimensiones);


	ventanaDeslizableGraficos.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
	ventanaDeslizableGraficos.set_size_request(160,118);
	referenciaModeloGraficos = Gtk::ListStore::create(columnasGraficos);
	visorModeloArbolGraficos.set_model(referenciaModeloGraficos);
	visorModeloArbolGraficos.append_column("Grafico", columnasGraficos.figura);
	visorModeloArbolGraficos.append_column("     Nombre", columnasGraficos.idColumna);
	ventanaDeslizableGraficos.add(visorModeloArbolGraficos);
}

void FrameEleccionTabla::on_manejador_cambios_tabla() {
	Glib::RefPtr<Gtk::TreeSelection> fila = visorModeloArbolArchivos.get_selection();
	Gtk::TreeModel::iterator iter = fila->get_selected();

	if(iter) {
	  Gtk::TreeModel::Row fila = *iter;
	  tablaElegida = fila[columnasArchivos.idColumna];

	  frameFiltros->limpiarCombos();

	  /***/
	  referenciaModeloHechos->clear();
	  referenciaModeloDimensiones->clear();
	  limpiarElegidos();
	  /*****/

	  std::vector<std::string>& hechos = gestorConfigHechos.getHechos(numerosT[tablaElegida]);
	  std::vector<std::string>::iterator itH = hechos.begin();
	  for(; itH != hechos.end(); itH++) {
		  agregarValorAHechos(*itH);
		  frameFiltros->agregarValorAHechos(*itH);
	  }

	  std::vector<std::string>& dimensiones = gestorConfigHechos.getDimensiones(numerosT[tablaElegida]);
	  std::vector<std::string>::iterator itD = dimensiones.begin();
	  	  for(; itD != dimensiones.end(); itD++) {
	  		  frameFiltros->agregarValorADimensiones(*itD);
	  		  std::string x = filtrarFecha(*itD);
	  		  agregarValorADimensiones(x);
	  	  }
	}
}

std::string FrameEleccionTabla::filtrarFecha(std::string& fecha) {
	size_t pos = fecha.find_first_of(Util::MARCAFECHA, 0);
	if(pos != std::string::npos)
		return fecha.substr(0,pos - 1);
	return fecha;
}

void FrameEleccionTabla::limpiarElegidos() {
	elegidoDimension = "";
	elegidosHechos.erase(elegidosHechos.begin(), elegidosHechos.end());
}

void FrameEleccionTabla::conectarManejadoresDeEvento() {
	Glib::RefPtr<Gtk::TreeSelection> refTabla = visorModeloArbolArchivos.get_selection();
	refTabla->signal_changed().connect(sigc::mem_fun(*this, &FrameEleccionTabla::on_manejador_cambios_tabla));

	Glib::RefPtr<Gtk::TreeSelection> refGrafico = visorModeloArbolGraficos.get_selection();
	refGrafico->signal_changed().connect(sigc::mem_fun(*this, &FrameEleccionTabla::on_seleccion_grafico));

	Glib::RefPtr<Gtk::TreeSelection> refDim = visorModeloArbolDimensiones.get_selection();
	refDim->signal_changed().connect(sigc::mem_fun(*this, &FrameEleccionTabla::on_manejador_cambios_tabla_Dimension));

	Glib::RefPtr<Gtk::TreeSelection> refH = visorModeloArbolHechos.get_selection();
	refH->set_mode(Gtk::SELECTION_MULTIPLE);
    refH->signal_changed().connect(sigc::mem_fun(*this, &FrameEleccionTabla::on_manejador_cambios_tabla_Hecho));
}

void FrameEleccionTabla::setDatosDeTablas() {
	size_t pos;
	std::string nombre;
	Gtk::TreeModel::Row fila;
	std::vector<std::string>&datos = gestorConfigHechos.getDatosDeTablas();
	std::vector<std::string>::iterator iterador = datos.begin();

	for(; iterador != datos.end(); iterador++) {
		pos = (*iterador).find_first_of(Util::SEPARADORFILECONSULTA,0);
		nombre = (*iterador).substr(pos + 1);
		numerosT[nombre] = (*iterador).substr(0, pos);
		fila = *(referenciaModeloArchivos->append());
		fila[columnasArchivos.idColumna] = nombre;
	}
}

void FrameEleccionTabla::agregarValorADimensiones(std::string &dato) {
	Gtk::TreeModel::Row fila = *(referenciaModeloDimensiones->append());
	fila[columnasDimensiones.idColumna] = dato.c_str();
}

void FrameEleccionTabla::agregarValorAHechos(std::string &dato) {
	Gtk::TreeModel::Row fila = *(referenciaModeloHechos->append());
	fila[columnasHechos.idColumna] = dato.c_str();
}

FrameEleccionTabla::~FrameEleccionTabla() {}


void FrameEleccionTabla::setNombresDatosGraficos() {
	setValorColumnaGrafico("barra.png", Util::GBARRAS);
	setValorColumnaGrafico("torta.png", Util::GTORTA);
	setValorColumnaGrafico("tabla1.png", Util::GTABLACOMUN);
	setValorColumnaGrafico("tabla2.png", Util::GTABLAPIVOTE);
}

void FrameEleccionTabla::setValorColumnaGrafico(const char* grafico, const std::string& nombre) {
	Gtk::TreeModel::Row fila = *(referenciaModeloGraficos->append());
	fila[columnasGraficos.figura] = Gdk::Pixbuf::create_from_file(grafico);
	fila[columnasGraficos.idColumna] = nombre;
	nombresGraficos.push_back(nombre);
}

void FrameEleccionTabla::on_manejador_cambios_tabla_Dimension() {
	Glib::RefPtr<Gtk::TreeSelection> fila = visorModeloArbolDimensiones.get_selection();
	Gtk::TreeModel::iterator iter = fila->get_selected();

	if(iter) {
	  Gtk::TreeModel::Row fila = *iter;
	  elegidoDimension = fila[columnasDimensiones.idColumna];
	}
}

void FrameEleccionTabla::on_seleccion_grafico() {
	Glib::RefPtr<Gtk::TreeSelection> fila = visorModeloArbolGraficos.get_selection();
	Gtk::TreeModel::iterator iter = fila->get_selected();

	if(iter) {
	  Gtk::TreeModel::Row fila = *iter;
	  graficoElegido = fila[columnasGraficos.idColumna];

	  if(graficoElegido.compare(Util::GTORTA) == 0)
		  nota.set_markup("<span font='8'> Selecciona sólo una dimensión para generar las\n "
				  "porciones de la torta y un hecho para darle el tamaño.</span>");
	  else {
		  if(graficoElegido.compare(Util::GBARRAS) == 0) {
			  nota.set_markup("<span font='8'>Selecciona una dimensión que se usará en el eje X\n"
			  "y uno o más hechos para generar el conjunto de barras.\n"
			  "Para seleccionar varios hechos, presiona la tecla Ctrl.</span>");
			 // std::cout<<graficoElegido<<std::endl;
		  }
		  else
			  nota.set_text("");
	  }
	  //std::cout<<graficoElegido<<std::endl;
	}
}

void FrameEleccionTabla::on_manejador_cambios_tabla_Hecho() {
	elegidosHechos.erase (elegidosHechos.begin(), elegidosHechos.end());
	visorModeloArbolHechos.get_selection()->selected_foreach_iter(sigc::mem_fun(*this, &FrameEleccionTabla::on_multiple_seleccion_hechos) );
}

void FrameEleccionTabla::on_multiple_seleccion_hechos(const Gtk::TreeModel::iterator& iter)  {
	Gtk::TreeModel::Row row = *iter;
	std::string valor = row[columnasHechos.idColumna];
	elegidosHechos.push_back(valor);
	//std::cout<<valor<<std::endl;
}

void FrameEleccionTabla::setFrameFiltro(FrameDeEleccionDeFiltros* frame) {
	frameFiltros = frame;
}

void FrameEleccionTabla::getGraficoElegido(std::string& grafico) {
	grafico = graficoElegido;

	if((graficoElegido.compare(Util::GTORTA) == 0) || (graficoElegido.compare(Util::GBARRAS) == 0)) {
		grafico.append(1, Util::PIPE);
		if(graficoElegido.compare(Util::GTORTA) == 0) {
			grafico.append(elegidoDimension);
			grafico.append(1, Util::PIPE);
			grafico.append(elegidosHechos[0]);
		}
		if(graficoElegido.compare(Util::GBARRAS) == 0) {
			grafico.append(elegidoDimension);
			std::vector<std::string>::iterator it = elegidosHechos.begin();
			for(;it != elegidosHechos.end(); it++) {
				grafico.append(1, Util::PIPE);
				grafico.append(*it);
			}
		}
	}
}

bool FrameEleccionTabla::eleccionCompleta() {
	if(!tablaElegida.empty() && !graficoElegido.empty()) {
		if(graficoElegido.compare(Util::GTORTA) == 0 || (graficoElegido.compare(Util::GBARRAS) == 0)) {
			if(!elegidoDimension.empty() && (elegidosHechos.size() > 0))
				return true;
			return false;
		}
		return true;
	}
	return false;
}

void FrameEleccionTabla::getDatosTablaElegida(std::string &numeroTabla, std::string &nombreTabla) {
	numeroTabla = numerosT[tablaElegida];
	nombreTabla = tablaElegida;
}
